﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.IO;

namespace belov_test
{
    public partial class AdminPanel : UserControl
    {
        private const int OFFSET = 10;
        private const double GRID_HEGTH_FACTOR = 0.9;
        
        private const int TESTS_NUM = 8;
        private const int EXCEL_FIRST_ROW = 2;

        private AdminInfo m_thisAdmin;
        private List<UserInfo> m_users = new List<UserInfo>();
        private List<AdminInfo> m_admins = new List<AdminInfo>();

        private MoreInfoForm m_moreInfoForm;
        private CreateAdminForm m_createAdminForm;
        private ChangePasswordForm m_changePasswordForm;

        private ExcelManager m_excelManager;

        public AdminPanel(String login)
        {
            InitializeComponent();
            m_users = InfoSerializer.LoadUsersInfo();
            ShowUsersInfo();

            this.HandleDestroyed += new EventHandler(OnAdminPanelDestroyed);

            m_admins = InfoSerializer.LoadAdminsInfo();
            
            for (int i = 0; i < m_admins.Count; i++)
            {
            	if (m_admins[i].Login == login)
            	{
                    m_thisAdmin = m_admins[i];
            	}
            }

            if (m_thisAdmin == null)
            {
                throw new Exception("Admin is not found!");
            }
        }

        private void OnAdminPanelDestroyed(object sender, EventArgs e)
        {
            Save();
        }

        public void DestroyPanel()
        {
            Save();
            Controls.Clear();
        }

        public void Save()
        {
            if (m_users != null)
            {
                InfoSerializer.SaveUsersInfo(m_users, false);
            }
            if (m_admins != null)
            {
                InfoSerializer.SaveAminsInfo(m_admins);
            }
        }

        private void ShowUsersInfo()
        {
            m_usersDataGridView.Rows.Clear();

            if (m_users == null)
            {
                return;
            }

            for (int i = 0; i < m_users.Count; i++)
            {
                UserInfo user = m_users[i];
                TestResult lastTestResult = user.GetLastTestResult();

                String cholericString = "-";
                String sanguineString = "-";
                String phlegmaticString = "-";
                String melancholiacString = "-";
                if (lastTestResult != null)
                {
                    cholericString = lastTestResult.cholericPercent.ToString() + "%";
                    sanguineString = lastTestResult.sanguinePercent.ToString() + "%";
                    phlegmaticString = lastTestResult.phlegmaticPercent.ToString() + "%";
                    melancholiacString = lastTestResult.melancholiacPercent.ToString() + "%";
                }

                String[] row = new String[] 
                { 
                    user.Surname,
                    user.Name,
                    user.Patronymic,
                    user.LastAccountUsing,
                    cholericString,
                    sanguineString,
                    phlegmaticString,
                    melancholiacString
                };

                m_usersDataGridView.Rows.Add(row);
            }
        }

        private void OnMoreInfoClicked(object sender, EventArgs e)
        {
            UserInfo user = GetCurrentUserInfo();
            if (user != null)
            {
                m_moreInfoForm = new MoreInfoForm(user);
                m_moreInfoForm.FormClosed += new FormClosedEventHandler(OnMoreInfoFormClosed);
                m_moreInfoForm.ShowDialog(this);
            }
        }

        private void OnMoreInfoFormClosed(object sender, FormClosedEventArgs e)
        {
            ShowUsersInfo();
        }

        private UserInfo GetCurrentUserInfo()
        {
            String name = m_usersDataGridView.CurrentRow.Cells[1].Value.ToString();
            String surname = m_usersDataGridView.CurrentRow.Cells[0].Value.ToString();
            String patronymic = m_usersDataGridView.CurrentRow.Cells[2].Value.ToString();

            for (int i = 0; i < m_users.Count; i++)
            {
                UserInfo user = m_users[i];
               
                if ((name == user.Name) && 
                    (surname == user.Surname) &&
                    (patronymic == user.Patronymic))
            	{
                    return user;
            	}
            }
            return null;
        }

        private void OnUserDelete(object sender, EventArgs e)
        {
            UserInfo user = GetCurrentUserInfo();
            
            if (MessageBox.Show("Вы действительно хотите удалить пользователя " + user.Name + " " + user.Surname + "?", 
                            "Подтверждение", MessageBoxButtons.YesNo,
                            MessageBoxIcon.Question) == DialogResult.Yes)
            {
                m_users.Remove(user);
                ShowUsersInfo();
                File.Delete(InfoSerializer.GetUserFilePath(user.Guid.ToString()));
            }
        }

        private void OnResized(object sender, EventArgs e)
        {
            m_usersDataGridView.Width = Width - m_usersDataGridView.Location.X * 2;
            m_usersDataGridView.Height = Convert.ToInt32(Convert.ToDouble(Height) * GRID_HEGTH_FACTOR);

            m_changePasswordBtn.Location = new Point(m_usersDataGridView.Location.X,
                                                     Height - m_changePasswordBtn.Height - OFFSET);

            m_createAdminBtn.Location = new Point(m_usersDataGridView.Location.X + m_changePasswordBtn.Width + OFFSET,
                                                  Height - m_changePasswordBtn.Height - OFFSET);

            m_toExcelBtn.Location = new Point(m_createAdminBtn.Location.X + m_createAdminBtn.Width + OFFSET,
                                                  Height - m_changePasswordBtn.Height - OFFSET);
        }

        private void OnPasswordChange(object sender, EventArgs e)
        {
            m_changePasswordForm = new ChangePasswordForm(m_thisAdmin.Password);
            m_changePasswordForm.FormClosing += new FormClosingEventHandler(OnChangePasswordFormClosing);
            m_changePasswordForm.ShowDialog(this);
        }

        private void OnChangePasswordFormClosing(object sender, FormClosingEventArgs e)
        {
            if (m_changePasswordForm.NewPassword != null)
            {
                m_thisAdmin.Password = m_changePasswordForm.NewPassword;
                MessageBox.Show("Пароль администратора \"" + m_thisAdmin.Login + "\" успешно обновлен!", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void OnNewAdminCreate(object sender, EventArgs e)
        {
            m_createAdminForm = new CreateAdminForm();
            m_createAdminForm.FormClosing += new FormClosingEventHandler(OnCreateAdminFormClosed);
            m_createAdminForm.ShowDialog(this);
        }

        private void OnCreateAdminFormClosed(object sender, FormClosingEventArgs e)
        {
            AdminInfo newAdmin = m_createAdminForm.NewAdmin;

            if (newAdmin != null)
            {
                for (int i = 0; i < m_admins.Count; i++)
                {
                    if (m_admins[i].Login == newAdmin.Login)
                	{
                        MessageBox.Show("Администратор \"" + newAdmin.Login + "\" уже существует!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }
                }
                m_admins.Add(newAdmin);
                MessageBox.Show("Администратор \"" + newAdmin.Login + "\" успешно создан!", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void OnSaveToExcel(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "Excel Files (*.xlsx) | *.xlsx";
            saveFileDialog.DefaultExt = "xlsx";
            
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                ExportDataToExcel(saveFileDialog.FileName);
            }
        }

        private void ExportDataToExcel(string fileName)
        {
            m_excelManager = new ExcelManager();

            CreateExcelTableStructure();
            ExportUsersInfoToExcel();

            m_excelManager.SaveAs(fileName);
            m_excelManager.CloseExcel();
        }
        
        private void CreateExcelTableStructure()
        {
            if (m_excelManager != null)
            {
                m_excelManager.SetCellValue("1", "A", "Фамилия");
                m_excelManager.SetCellValue("1", "B", "Имя");
                m_excelManager.SetCellValue("1", "C", "Отчество");
                m_excelManager.SetCellValue("1", "D", "Последние действия");
                m_excelManager.SetCellValue("1", "E", "Дата начала");
                m_excelManager.SetCellValue("1", "F", "Дата окончания");
                m_excelManager.SetCellValue("1", "G", "Холерик (%)");
                m_excelManager.SetCellValue("1", "H", "Сангвиник (%)");
                m_excelManager.SetCellValue("1", "I", "Флегматик (%)");
                m_excelManager.SetCellValue("1", "J", "Меланхолик (%)");

                m_excelManager.SetColumnsWidth(20);
                m_excelManager.SetRangeFontBoldProperty("A1", "J1", true);

                m_excelManager.SetRangeBottomLineWeight("A1", "J1", 4);
            }
        }

        private void ExportUsersInfoToExcel()
        {
            if (m_excelManager != null)
            {
                for (int i = 0; i < m_users.Count; i++)
                {
                    ExportUserInfoToExcel(m_users[i], i);
                }
            }
        }

        private void ExportUserInfoToExcel(UserInfo userInfo, int line)
        {
            int testsNum = Math.Max(userInfo.GetTestResultsCount(), 1);
            int startRow = EXCEL_FIRST_ROW + line * testsNum;
            int finishRow = startRow + testsNum;

            m_excelManager.SetCellValue(startRow.ToString(), "A", userInfo.Surname);
            m_excelManager.MergeCells("A" + startRow.ToString(), "A" + (finishRow - 1).ToString());

            m_excelManager.SetCellValue(startRow.ToString(), "B", userInfo.Name);
            m_excelManager.MergeCells("B" + startRow.ToString(), "B" + (finishRow - 1).ToString());

            m_excelManager.SetCellValue(startRow.ToString(), "C", userInfo.Patronymic);
            m_excelManager.MergeCells("C" + startRow.ToString(), "C" + (finishRow - 1).ToString());

            m_excelManager.SetCellValue(startRow.ToString(), "D", userInfo.LastAccountUsing);
            m_excelManager.MergeCells("D" + startRow.ToString(), "D" + (finishRow - 1).ToString());

            for (int i = startRow; i < finishRow; i++)
            {
                ExportTestResultToExcel(userInfo.GetTestResult(i - startRow), i.ToString());
            }
            if (userInfo.GetTestResultsCount() == 0)
            {
                m_excelManager.SetCellValue(startRow.ToString(), "G", "Тест не пройден");
                m_excelManager.SetCellValue(startRow.ToString(), "H", "Тест не пройден");
                m_excelManager.SetCellValue(startRow.ToString(), "I", "Тест не пройден");
                m_excelManager.SetCellValue(startRow.ToString(), "J", "Тест не пройден");
            }


            m_excelManager.SetRangeBottomLineWeight("A" + startRow.ToString(), "J" + (finishRow - 1).ToString(), 3);
        }

        private void ExportTestResultToExcel(TestResult testResult, string row)
        {
            m_excelManager.SetCellValue(row, "E", testResult.BeginTime);
            m_excelManager.SetCellValue(row, "F", testResult.EndTime);
            m_excelManager.SetCellValue(row, "G", testResult.cholericPercent.ToString());
            m_excelManager.SetCellValue(row, "H", testResult.sanguinePercent.ToString());
            m_excelManager.SetCellValue(row, "I", testResult.phlegmaticPercent.ToString());
            m_excelManager.SetCellValue(row, "J", testResult.melancholiacPercent.ToString());
        }
    }
}